package cn.lili.modules.member.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.utils.*;
import cn.lili.common.vo.PageVO;
import cn.lili.common.vo.ResultMessage;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.constant.CommonConstant;
import cn.lili.modules.distribution.client.DistributionClient;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.member.entity.dto.*;
import cn.lili.modules.member.entity.vo.UserVO;
import cn.lili.modules.member.mapper.UserMapper;
import cn.lili.modules.member.service.UserService;
import cn.lili.modules.operationcenter.client.OperationCenterClient;
import cn.lili.modules.operationcenter.entity.dos.OperationCenter;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.entity.dos.OrderFlow;
import cn.lili.modules.order.order.entity.dto.UserFlowDTO;
import cn.lili.modules.order.order.entity.enums.ProfitSharingStatusEnum;
import cn.lili.modules.order.order.entity.vo.TeamTreeVO;
import cn.lili.modules.permission.entity.dto.UserAdminDTO;
import cn.lili.modules.sensitive.SensitiveWordsFilter;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dos.UserPageDto;
import cn.lili.modules.system.entity.dto.DistributionSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.routing.UserRoutingKey;
import com.alibaba.fastjson.JSONObject;
import com.api.UserApi;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pojos.OpenAppUser;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户接口业务层实现
 *
 * @author Chopper
 * @since 2021-03-29 14:10:16
 */
@Service
@AllArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    private final ApplicationEventPublisher applicationEventPublisher;

    private final AmqpExchangeProperties amqpExchangeProperties;

    private final Cache cache;
    private final DistributionClient distributionClient;
    private final OrderClient orderClient;
    private final SettingClient settingClient;

    private final UserApi userApi;
    private final OperationCenterClient operationCenterClient;

    @Override
    public User findByUsername(String userName, SceneEnums scene) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, userName);
        queryWrapper.eq(User::getScene, scene.value());
        return this.baseMapper.selectOne(queryWrapper);
    }


    @Override
    public UserVO userInfo() {
        AuthUser authUser = UserContext.getCurrentUser();
        assert authUser != null;
        User user = this.getById(authUser.getId());
        UserVO userVO = new UserVO(user);
        log.info("userInfo == {}", JSONObject.toJSONString(user));
        if (user != null && StringUtils.isNotEmpty(user.getId())) {
            log.info("user.getId() == {}", user.getId());
            OperationCenter operationCenter = operationCenterClient.getOperationCenter(user.getId());
            log.info("operationCenter = {}", JSONObject.toJSONString(operationCenter));
            userVO.setOperationName(operationCenter != null ? operationCenter.getOperationName() : null);
            log.info("userVO = {}", JSONObject.toJSONString(userVO));
        }
        return userVO;
    }


    @Override
    public User userLoginQuery(UserLoginDTO userLoginDTO) {
        User user = this.findByUsername(userLoginDTO.getUsername(), userLoginDTO.getScene());
        //判断用户是否存在
        if (user == null || !user.getEnable()) {
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        //判断密码是否输入正确
//        System.out.println("new BCryptPasswordEncoder().encode(userLoginDTO.getPassword()) = " + new BCryptPasswordEncoder().encode(userLoginDTO.getPassword()));
//        if (!new BCryptPasswordEncoder().matches(userLoginDTO.getPassword(), user.getPassword())) {
//            throw new ServiceException(ResultCode.USER_PASSWORD_ERROR);
//        }
        return user;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public User mobilePhoneLogin(String mobilePhone, SceneEnums scene) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobilePhone);
        queryWrapper.eq("scene", scene.value());
        User user = this.baseMapper.selectOne(queryWrapper);
        //如果手机号不存在则自动注册用户
        if (user == null) {
            UserInfoDTO userInfoDTO =
                    UserInfoDTO.builder().username(mobilePhone).mobile(mobilePhone).scene(scene).password(UserService.DEFAULT_PASSWORD).build();

            user = registerHandler(userInfoDTO);
        }
        return user;
    }


    @Override
    public User editOwn(UserEditBaseDTO userEditBaseDTO) {
        //查询用户信息
        User user = this.findByUsername(UserContext.getCurrentUser().getUsername(), UserContext.getCurrentUser().getScene());
        //传递修改用户信息
        BeanUtil.copyProperties(userEditBaseDTO, user);
        /*if (SceneEnums.URBAN_SUBSTATION.equals(UserContext.getCurrentUser().getScene())) {
            user.setId(UserContext.getCurrentUser().getId());
        }else {
            user.setId(UserContext.getCurrentId());
        }*/



        //修改用户
        this.updateById(user);
        return user;
    }


    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public User addUser(UserInfoDTO userInfoDTO) {
        //检测用户信息
        checkMember(userInfoDTO.getUsername(), userInfoDTO.getMobile(), userInfoDTO.getScene().value());
        //添加用户
        userInfoDTO.setPassword(new BCryptPasswordEncoder().encode(userInfoDTO.getPassword()));
        return registerHandler(userInfoDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVO updateUser(UserInfoDTO userInfoDTO) {
        //过滤用户昵称敏感词
        if (CharSequenceUtil.isNotBlank(userInfoDTO.getNickName())) {
            userInfoDTO.setNickName(SensitiveWordsFilter.filter(userInfoDTO.getNickName()));
        }
        //如果密码不为空则加密密码
        if (CharSequenceUtil.isNotBlank(userInfoDTO.getPassword())) {
            userInfoDTO.setPassword(new BCryptPasswordEncoder().encode(userInfoDTO.getPassword()));
        }

        if (userInfoDTO.getBirthday() != null && userInfoDTO.getBirthday().after(new Date())) {
            throw new ServiceException(ResultCode.PARAMS_ERROR, "生日不能大于当前日期");
        }
        //查询用户信息
        User user = this.getById(userInfoDTO.getId());

        //编辑用户时需要先判定用户信息是否可以编辑，判定依据为：修改用户的逻辑场景是否与数据库中一致，避免跨业务修改
        if (user == null || !SceneEnums.getScene(user.getScene()).equals(userInfoDTO.getScene())) {
            throw new ServiceException(ResultCode.USER_NOT_EXIST);
        }
        //上级账号传值,则是更改上级账号关系
        if (StringUtils.isNotEmpty(userInfoDTO.getParentUsername())) {
            User parentUser = this.findByUsername(userInfoDTO.getParentUsername(), SceneEnums.MEMBER);
            if (parentUser == null) {
                throw new ServiceException(ResultCode.PARENT_NOT_FOUND);
            }
            //绑定上级
            user.setParentId(parentUser.getId());
            user.setParentUsername(StringUtils.isNotEmpty(parentUser.getUsername()) ? parentUser.getUsername() : "");
            Distribution dis = new Distribution();
            dis.setMemberId(user.getId());
            dis.setParentId(parentUser.getId());
            dis.setParentUsername(user.getParentUsername());
            distributionClient.updateDistributionParentInfo(dis);
            //上级绑定时间
            user.setParentBindTime(new Date());
        }

        //传递修改用户信息
        BeanUtil.copyProperties(userInfoDTO, user);
        this.updateById(user);
        cache.vagueDel(CachePrefix.USER_MENU.getPrefix(SceneEnums.valueOf(user.getScene()), user.getId()));
        cache.vagueDel(CachePrefix.PERMISSION_LIST.getPrefix(SceneEnums.valueOf(user.getScene()), user.getId()));
        return new UserVO(user);
    }



    /**
     * 清空上级ID
     * @param userId 用户ID
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean clearParent(String userId) {
        //清空用户表上面的上级ID
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId);
        updateWrapper.set(User::getParentId, null);
        updateWrapper.set(User::getParentUsername, null);
        updateWrapper.set(User::getParentBindTime, null);
        super.update(updateWrapper);

        //清空店主表上的用户ID
        Distribution dis = new Distribution();
        dis.setMemberId(userId);
        boolean flag = distributionClient.clearParentInfo(dis);
        if (!flag) {
            throw new ServiceException("清空失败,请稍候再试");
        }
        cache.remove(CommonConstant.TEMP_SHARE_GOODS_PARENT_KEY + userId);
        cache.remove(CommonConstant.EXIST_SHARE_GOODS_RELATIONSHIP + userId);
        return flag;
    }

    @Override
    public Page<UserVO> getUserPage(UserSearchParams userSearchParams, PageVO page) {
        QueryWrapper<User> queryWrapper = Wrappers.query();

        //用户名查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getUsername()), "username", userSearchParams.getUsername());
        //用户名查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getNickName()), "nick_name", userSearchParams.getNickName());
        //按照电话号码查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getMobile()), "mobile", userSearchParams.getMobile());
        //按照用户状态查询
        queryWrapper.eq(userSearchParams.getEnable() != null, "enable", userSearchParams.getEnable()); //按照用户状态查询
        //必填场景参数
        queryWrapper.eq("scene", userSearchParams.getScene().name());
        //邀请人ID查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getParentUsername()),"parent_username",userSearchParams.getParentUsername());

        queryWrapper.orderByDesc("create_time");
        return this.baseMapper.memberPage(PageUtil.initPage(page), queryWrapper);
    }

    /**
     * 会员导出
     * @param userSearchParams
     * @return
     */
    @Override
    public List<MemberExportDTO> queryExportMember (UserSearchParams userSearchParams) {
        QueryWrapper<User> queryWrapper = Wrappers.query();
        //用户名查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getUsername()), "lu.username", userSearchParams.getUsername());
        //用户名查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getNickName()), "lu.nick_name", userSearchParams.getNickName());
        //按照电话号码查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getMobile()), "lu.mobile", userSearchParams.getMobile());
        //按照用户状态查询
        queryWrapper.eq(userSearchParams.getEnable() != null, "lu.enable", userSearchParams.getEnable()); //按照用户状态查询
        //必填场景参数
        queryWrapper.eq("lu.scene", userSearchParams.getScene().name());

        queryWrapper.orderByDesc("create_time");
        List<MemberExportDTO> userVOList = this.baseMapper.queryExportMember(queryWrapper);
        return userVOList;
    }

    /**
     * 获取用户列表
     *
     * @param searchParams 查询参数
     * @return 用户列表
     */
    @Override
    public List<User> list(UserSearchParams searchParams) {
        if (searchParams.getPageNumber() > 0 && searchParams.getPageSize() > 0) {
            return this.page(PageUtil.initPage(searchParams), searchParams.queryWrapper()).getRecords();
        }
        return this.list(searchParams.queryWrapper());
    }
    @Override
    public List<User> select(String name) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
        lambdaQueryWrapper.eq(User::getScene, SceneEnums.MEMBER.name());
        lambdaQueryWrapper.select(User::getUsername, User::getId);
        lambdaQueryWrapper.last("limit 10");
        if (StringUtils.isNotEmpty(name)) {
            lambdaQueryWrapper.like(User::getUsername, name);
        }
        return super.list(lambdaQueryWrapper);
    }

    @Override
    public String getOpenIdByFy() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>();
        lambdaQueryWrapper.likeRight(User::getOpenId, "fy_");
        lambdaQueryWrapper.last("limit 1");
        return this.getOne(lambdaQueryWrapper).getOpenId();
    }

    @Override
    public Boolean updateUserStatus(UserStatusChangeDTO userStatusChangeDTO) {
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getScene, userStatusChangeDTO.getScene().value());
        updateWrapper.set(User::getEnable, userStatusChangeDTO.getEnable());
        updateWrapper.in(User::getId, userStatusChangeDTO.getUserIds());
        boolean update = this.update(updateWrapper);
        if (update && !userStatusChangeDTO.getEnable()) {
            for (String userId : userStatusChangeDTO.getUserIds()) {
                cache.vagueDel(CachePrefix.ACCESS_TOKEN.getPrefix(userStatusChangeDTO.getScene(), userId));
                cache.vagueDel(CachePrefix.REFRESH_TOKEN.getPrefix(userStatusChangeDTO.getScene(), userId));
            }
        }
        return update;
    }

    @Override
    public long getMemberNum(UserSearchParams userSearchParams) {
        QueryWrapper<User> queryWrapper = Wrappers.query();
        //用户名查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getUsername()), "username", userSearchParams.getUsername());
        //按照电话号码查询
        queryWrapper.like(CharSequenceUtil.isNotBlank(userSearchParams.getMobile()), "mobile", userSearchParams.getMobile());
        //按照状态查询
        queryWrapper.eq(userSearchParams.getEnable() != null, "enable", userSearchParams.getEnable());
        //场景筛选
        queryWrapper.eq("scene", userSearchParams.getScene().name());
        queryWrapper.orderByDesc("create_time");
        return this.count(queryWrapper);
    }

    /**
     * 获取指定用户数据
     *
     * @param columns 指定获取的列
     * @param userIds 用户ids
     * @return 指定用户数据
     */
    @Override
    public List<Map<String, Object>> listFieldsByMemberIds(String columns, List<String> userIds) {
        return this.listMaps(new QueryWrapper<User>().select(columns).in(userIds != null && !userIds.isEmpty(), "id", userIds));
    }

    /**
     * 获取所有用户的手机号
     *
     * @return 所有用户的手机号
     */
    @Override
    public List<String> getMemberMobile(PageVO pageVO) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getEnable, true);
        return this.baseMapper.getAllMemberMobile(PageUtil.initPage(pageVO), lambdaQueryWrapper);
    }

    /**
     * 更新用户登录时间为最新时间
     *
     * @param userId 用户id
     * @return 是否更新成功
     */
    @Override
    public Boolean updateUserLoginTime(String userId) {
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId);
        updateWrapper.set(User::getLastLoginDate, new Date());
        return this.update(updateWrapper);
    }


    /**
     * 注册方法抽象
     *
     * @param userInfoDTO 注册传输对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public User registerHandler(UserInfoDTO userInfoDTO) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(User::getMobile, userInfoDTO.getMobile());
        queryWrapper.eq(User::getScene, userInfoDTO.getScene().value());
        if (this.count(queryWrapper) > 0) {
            throw new ServiceException(ResultCode.USER_EXIST);
        }
        User user = new User(userInfoDTO);
        user.setId(SnowFlake.getIdStr());
        //保存用户
        this.save(user);

        applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("USER_REGISTER").exchange(amqpExchangeProperties.getUser()).routingKey(UserRoutingKey.USER_REGISTER).message(user).build());
        return user;
    }


    @Override
    public void saveUser(UserAdminDTO userAdminDTO) {
        this.save(new User(userAdminDTO));
    }

    @Override
    public void updateSceneId(String userId, String sceneId) {
        LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.set(User::getExtendId, sceneId);
        updateWrapper.eq(User::getId, userId);
        this.update(updateWrapper);
    }


    @Override
    public List<User> getUserByDepartmentIds(List<String> departmentIds) {
        if (departmentIds == null || departmentIds.size() == 0) {
            return new ArrayList<>();
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("department_id", departmentIds);
        return this.list(queryWrapper);
    }

    /**
     * 检测用户
     *
     * @param userName    用户名称
     * @param mobilePhone 手机号
     */
    private void checkMember(String userName, String mobilePhone, String scene) {
        //判断手机号是否存在
        if (findUser(mobilePhone, userName, scene) > 0) {
            throw new ServiceException(ResultCode.USER_EXIST);
        }
    }


    /**
     * 根据手机号获取用户
     *
     * @param mobilePhone 手机号
     * @param userName    用户名
     * @param scene       场景
     * @return 用户
     */
    private Long findUser(String mobilePhone, String userName, String scene) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getScene, scene).and(i -> {
            i.eq(User::getMobile, mobilePhone).or().eq(User::getUsername, userName);
        });
        return this.baseMapper.selectCount(queryWrapper);
    }

    /**
     * 分销商入驻
     *
     * @param user 用户信息
     * @return 是否成功
     */
    @Override
    public Boolean supplierSave(User user) {
        Date date = new Date();
        user.setAuditStatus(CommonConstant.AUDIT_STATUS_00);
        user.setScene(SceneEnums.SUPPLIER.name());
        user.setEnable(true);
        user.setCreateTime(date);
        user.setDeleteFlag(false);
        user.setIsSuper(false);
        user.setIsSuper(false);

        return super.save(user);
    }

    @Override
    public User getByExtId(String extId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getExtendId, extId);
        queryWrapper.last("limit 1");
        User userList = this.baseMapper.selectOne(queryWrapper);
        return userList;
    }

    @Override
    public User getByExtId2(String extId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getExtendId, extId);
        queryWrapper.eq(User::getShopkeeper,"1");
        queryWrapper.last("limit 1");
        User userList = this.baseMapper.selectOne(queryWrapper);
        return userList;
    }

    @Override
    public Boolean deleteUserByExtId(String extId) {
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getExtendId, extId);
        updateWrapper.set(User::getDeleteFlag,1);
        return this.baseMapper.update(null,updateWrapper)>0;
    }

    @Override
    public ResultMessage<Object> getUserNotVip(UserPageDto dto) {
        //获取非plus会员的正常用户
        LambdaQueryWrapper<User>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(User::getEnable,1)
                .like(StringUtils.isNotEmpty(dto.getUserName()),User::getUsername,dto.getUserName())
                .like(StringUtils.isNotEmpty(dto.getNickName()),User::getNickName,dto.getNickName())
                .like(StringUtils.isNotEmpty(dto.getMobile()),User::getMobile,dto.getMobile())
                .orderByDesc(User::getCreateTime)
                .eq(Objects.nonNull(dto.getSex()),User::getSex,dto.getSex());
        Page<User> page = this.baseMapper.selectPage(new Page<>(dto.getPageNumber(), dto.getPageSize()), wrapper);
        return ResultUtil.data(page);
    }


    @Override
    public Map<String, Integer> selectUserChildCountByUserIds(List<String> userIds) {
        Map<String, Integer> map = null;
        List<UserVO> userVos = baseMapper.selectUserChildCountByUserIds(userIds);
        if (CollUtil.isNotEmpty(userVos)) {
            //转成map
            map = userVos.stream().collect(Collectors.toMap(UserVO::getId, v -> v.getChildCount()));
        }
        return map;
    }

    /**
     * 根据店主用户ids查询下级id
     * @param userIds
     * @return
     */
    @Override
    public Map<String, List<String>> selectChildUserIdsByMemberIds(List<String> userIds) {
        Map<String, List<String>> map = new HashMap<>();
        List<UserVO> userVos = baseMapper.selectChildUserIdsByMemberIds(userIds);
        if (CollUtil.isNotEmpty(userVos)) {
            for (UserVO vo : userVos) {
                List<String> subIds = map.get(vo.getParentId());
                if (CollUtil.isEmpty(subIds)) {
                    subIds = new ArrayList<>();
                    subIds.add(vo.getParentId());
                    map.put(vo.getParentId(), subIds);
                } else {
                    subIds.add(vo.getId());
                }
            }
        }
        return map;
    }

    @Override
    public String callGetSubordinatesAndSubSubordinates(String currentId) {
        // 创建输出参数的容器
        List<UserFlowDTO> userFlowDTOList = baseMapper.getLowerAndLowerSubByParentId(currentId, DateUtil.format(new Date(), "yyyy-MM"), ProfitSharingStatusEnum.FINISHED.name(), null);
        // 获取返回结果
        String result = "";
        if (CollectionUtil.isNotEmpty(userFlowDTOList)) {
            result = userFlowDTOList.stream().map(UserFlowDTO::getId).collect(Collectors.joining(","));
        }
        return result;
    }

    public String getSubordinatesAndSubSubordinatesSearchName(String nickName) {
        List<UserFlowDTO> userFlowDTOList = baseMapper.getLowerAndLowerSubByParentId(UserContext.getCurrentId(), DateUtil.format(new Date(), "yyyy-MM"), ProfitSharingStatusEnum.FINISHED.name(), nickName);
        String result = "";
        if (CollectionUtil.isNotEmpty(userFlowDTOList)) {
            result = userFlowDTOList.stream().map(UserFlowDTO::getId).collect(Collectors.joining(","));
        }
        return result;
    }

    /**
     * 团队树
     * @param searchName 搜索条件
     * @return 团队树
     */
    @Override
    public List<TeamTreeVO> teamTree(String searchName) {
        String uids = this.getSubordinatesAndSubSubordinatesSearchName(searchName);
        List<User> userList = super.list(new LambdaQueryWrapper<User>().in(User::getId, (Object[]) uids.split(",")));
        //获取本月金额 与 用户类型
        this.compute(userList);
        //转树型结构
        return this.convertToTree(userList);
    }

    /**
     * 获取本月金额 与 用户类型
     */
    private void compute(List<User> userList) {
        if (CollectionUtil.isEmpty(userList)) {
            return;
        }
        List<String> userIdList = userList.stream().map(User::getId).toList();
        List<OrderFlow> userMoneyList = orderClient.computeMoney(userIdList);
        Map<String, Integer> userTypeMap = distributionClient.computeType(userIdList);
        for (User user : userList) {
            user.setMoney(BigDecimal.valueOf(0));
            //本月金额
            if (CollectionUtil.isNotEmpty(userMoneyList)) {
                for (OrderFlow orderFlow : userMoneyList) {
                    if (user.getId().equals(orderFlow.getMemberId())) {
                        user.setMoney(BigDecimal.valueOf(orderFlow.getFlowPrice()));
                    }
                }
            }
            //用户类型
            if (CollectionUtil.isNotEmpty(userTypeMap)) {
                user.setType(userTypeMap.get(user.getId()));
            }
        }
    }

    /**
     * 转成树形结构
     * @param userList 用户列表
     * @return 转成树形结构
     */
    public List<TeamTreeVO> convertToTree(List<User> userList) {
        if (CollectionUtil.isEmpty(userList)) {
            return new ArrayList<>();
        }
        List<TeamTreeVO> roots = new ArrayList<>();
        Map<String, List<TeamTreeVO>> childrenMap = new HashMap<>();
        // 将用户按照父节点分组
        for (User user : userList) {
            if (Objects.equals(user.getParentId(), UserContext.getCurrentId())) {
                TeamTreeVO root = new TeamTreeVO();
                root.setId(user.getId());
                root.setType(user.getType());
                root.setNickName(user.getNickName());
                root.setFace(user.getFace());
                root.setMoney(user.getMoney());
                root.setChildren(new ArrayList<>());
                roots.add(root);
            } else {
                //类型是店主的，不放到间推里面去。
                if (user.getType() == 2) {
                    continue;
                }
                TeamTreeVO node = new TeamTreeVO();
                node.setId(user.getId());
                node.setType(user.getType());
                node.setNickName(user.getNickName());
                node.setFace(user.getFace());
                node.setMoney(user.getMoney());
                node.setChildren(new ArrayList<>());
                List<TeamTreeVO> children = childrenMap.computeIfAbsent(user.getParentId(), k -> new ArrayList<>());
                children.add(node);
            }
        }
        // 递归构建树形结构
        for (TeamTreeVO root : roots) {
            buildSubTree(root, childrenMap);
        }
        return roots;
    }

    private void buildSubTree(TeamTreeVO parent, Map<String, List<TeamTreeVO>> childrenMap) {
        List<TeamTreeVO> children = childrenMap.get(parent.getId());
        if (children != null) {
            parent.setChildren(children);
            for (TeamTreeVO child : children) {
                buildSubTree(child, childrenMap);
            }
        }
    }

    /**
     * 下级列表
     * @param dto
     * @return
     */
    @Override
    public Page<User> getLowerUserList(UserQueryDTO dto) {
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.eq(User::getParentId, dto.getParentId());
        if (StringUtils.isNotEmpty(dto.getUserId())) {
            query.eq(User::getId, dto.getUserId());
        }
        if (StringUtils.isNotEmpty(dto.getAccount())) {
            query.like(User::getAccount, dto.getAccount());
        }
        if (StringUtils.isNotEmpty(dto.getNickName())) {
            query.eq(User::getNickName, dto.getNickName());
        }
        if (dto.getIsDistribution() != null) {
            if (dto.getIsDistribution() == 1) {
                query.eq(User::getIsDistribution, Boolean.TRUE);
            }
            if (dto.getIsDistribution() == 0) {
                query.and(q -> q.eq(User::getIsDistribution, Boolean.FALSE).or().isNull(User::getIsDistribution));
            }
        }

        Page<User> page = baseMapper.selectPage(new Page<>(dto.getPageNumber(), dto.getPageSize()), query);
        if(CollUtil.isNotEmpty(page.getRecords())){
            //查询订单数量
            List<String> userids = page.getRecords().stream().map(User::getId).collect(Collectors.toList());
            Map<String, Integer> orderMap = orderClient.selectCountOrderByUserIds(userids, dto.getParentId());
            Map<String, Double> currentConsumptionMap = orderClient.selectCurrentConsumptionByUserIds(userids, dto.getParentId());
            Map<String, Double> cumulativeConsumptionMap = orderClient.selectCumulativeConsumptionByUserIds(userids, dto.getParentId());
            page.getRecords().stream().forEach(e -> {
                //是否是店长
                if (null != e.getIsDistribution() && e.getIsDistribution()) {
                    e.setIsDistributionName("店主");
                } else {
                    e.setIsDistributionName("用户");
                }
                //订单数量
                if(CollUtil.isNotEmpty(orderMap)){
                    e.setOrderCount(orderMap.get(e.getId()) != null ? orderMap.get(e.getId()) : 0);
                }
                e.setCurrentConsumption(0D);
                e.setCumulativeConsumption(0D);
                if(CollUtil.isNotEmpty(currentConsumptionMap)){
                    e.setCurrentConsumption((double) (currentConsumptionMap.get(e.getId()) != null ? currentConsumptionMap.get(e.getId()) : 0));
                }
                if(CollUtil.isNotEmpty(cumulativeConsumptionMap)){
                    e.setCumulativeConsumption((double) (cumulativeConsumptionMap.get(e.getId()) != null ? cumulativeConsumptionMap.get(e.getId()) : 0));
                }
            });
        }
        return page;
    }

    /**
     * 根据邀请人ID查询下级用户(直推用户)
     * @param parentId 邀请人ID
     * @return 直推用户集合
     * */
    @Override
    public List<User> getLowerByParentId(String parentId) {
        return this.baseMapper.getLowerByParentId(parentId);
    }

    /**
     * 根据邀请人ID查询下级用户(直推用户数量)
     * @param parentId 邀请人ID
     * @return 直推用户数量
     * */
    @Override
    public Integer getCountLowerByParentId(String parentId) {
        return this.baseMapper.getCountLowerByParentId(parentId);
    }

    /**
     * 根据邀请人ID查询下级用户（间推用户）
     * @param parentId 邀请人ID
     * @return 间推用户集合
     * */
    @Override
    public List<User> getLowerSubByParentId(String parentId) {
        return this.baseMapper.getLowerSubByParentId(parentId);
    }

    /**
     * 根据邀请人ID查询下级用户（间推用户数量）
     * @param parentId 邀请人ID
     * @return 间推用户集合
     * */
    @Override
    public Integer getCountLowerSubByParentId(String parentId) {
        return this.baseMapper.getCountLowerSubByParentId(parentId);
    }

    /**
     * 根据邀请人ID和时间查询直推用户及间推用户+用户类型+分销类型+业绩+收益
     * @param parentId 邀请人ID
     * @param flowTime 计算流水时间-年月 如：2024-01
     * @param profitSharing 结算状态
     * @return 直推用户及间推用户
     * */
    @Override
    public List<UserFlowDTO> getLowerAndLowerSubByParentId(String parentId, String flowTime, String profitSharing) {
        return this.baseMapper.getLowerAndLowerSubByParentId(parentId, flowTime, profitSharing, null);
    }

    /**
     * 查询团队树
     * @param parentId 邀请人ID
     * @param flowTime 计算流水时间-年月 如：2024-01
     * @param profitSharing 结算状态
     * @return 直推用户及间推用户
     * */
    @Override
    public List<UserFlowDTO> getLowerAndLowerSubByParentIdTree(String parentId, String flowTime,String profitSharing) {
        List<UserFlowDTO> flowDTOList = this.baseMapper.getLowerAndLowerSubByParentId(parentId,flowTime,profitSharing,null);
        //直推用户
        List<UserFlowDTO> parentList = Optional.of(flowDTOList).orElse(List.of()).stream().filter(dto ->"1".equals(dto.getLowerType())).collect(Collectors.toList());
        //间推用户
        parentList.forEach(parentUser -> {
            List<UserFlowDTO> tree = flowDTOList.stream()
                    .filter(allUser -> parentUser.getId().equals(allUser.getParentId()))
                    .collect(Collectors.toList());
            parentUser.setTree(tree);
        });
        return parentList;
    }

    @Override
    public List<User> findByIdList(List<String> chairmanIdList){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(User::getId,chairmanIdList);
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }


    public int clearUnion(String memberId){
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId,memberId);
        updateWrapper.set(User::getUnionId,null);
        return this.baseMapper.update(null,updateWrapper);
    }


    /**
     * 根据account搜索满足城主条件的用户
     * @param
     * @return
     */
    @Override
    public List<User> selectUserForCityDistributionByAccount(UserQueryDTO dto) {
        //所需下级店主人数
//        Setting setting = settingClient.get(SettingEnum.DISTRIBUTION_SETTING.name());
//        DistributionSetting distributionSetting = JSONUtil.toBean(setting.getSettingValue(), DistributionSetting.class);
//        if (distributionSetting != null && StringUtils.isNotEmpty(distributionSetting.getCastellan())) {
//            dto.setSubDistributionCount(Integer.valueOf(distributionSetting.getCastellan()));
//        }else{
//            dto.setSubDistributionCount(20);
//        }
        return baseMapper.selectUserForCityDistributionByAccount(new Page(dto.getPageNumber(), dto.getPageSize()), dto);
    }


    public List<UnionMemberDetailDTO>  countChilds(String memberId){
        return baseMapper.countChilds(memberId);
    }

    public Integer isAuth () {
        OpenAppUser openAppUser = userApi.getUserinfoByOpenId(UserContext.getCurrentUser().getOpenId());
        if (null == openAppUser) {
            return 0;
        }
        boolean authenticationFlag = userApi.isAuthentication(openAppUser.getUId());
        return authenticationFlag ? 1 : 0;
    }


    /**
     * 查询redis里的临时分享商品关系
     * @param redisKey
     * @return
     */
    @Override
    public String queryShareGoodsBindParent(String redisKey) {
        Object obj = cache.get(redisKey);
        return obj == null ? "null" : JSONObject.toJSONString(obj);
    }
}